package xyz.tanxiao.links.common.utils;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.Getter;
import xyz.tanxiao.links.common.enums.MappingKeyStatusEnum;
import xyz.tanxiao.links.entity.SlLinkAccess;
import xyz.tanxiao.links.entity.SlLinkMapping;
import xyz.tanxiao.links.service.SlLinkAccessService;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 短链接映射验证器
 *
 * @author 万成波
 * @email 2300064869@qq.com
 * @createTime 2023-06-15 18:54:16 星期四
 */
public class LinkMappingValidator {

	/**
	 * 验证结果：true 验证通过、false 验证不通过
	 */
	@Getter
	private boolean verifyResult = true;

	/**
	 * 验证消息
	 */
	@Getter
	private String verifyMessage = "访问成功，已重定向。";

	/**
	 * 链接映射源
	 */
	private static SlLinkMapping mapping;


	/**
	 * 设置验证源
	 *
	 * @param mapping 短链接映射信息
	 * @return 初始化的验证器
	 */
	public static LinkMappingValidator setVerifyMapping(SlLinkMapping mapping) {
		LinkMappingValidator.mapping = mapping;
		return new LinkMappingValidator();
	}


	/**
	 * 1、验证短链接映射状态
	 *
	 * @return 当前验证器
	 */
	public LinkMappingValidator verifyMappingStatus() {
		if (this.verifyResult) {
			MappingKeyStatusEnum shortStatus = MappingKeyStatusEnum.getByStatus(mapping.getStatus());
			if (MappingKeyStatusEnum.NORMAL != shortStatus) {
				this.verifyResult = false;
				this.verifyMessage = shortStatus.getMessage();
			}
		}
		return this;
	}


	/**
	 * 2、验证短链接映射启用时间
	 *
	 * @return 当前验证器
	 */
	public LinkMappingValidator verifyEnableTime() {
		if (this.verifyResult) {
			LocalDateTime enableTime = mapping.getEnableTime();
			if (Objects.nonNull(enableTime) && LocalDateTime.now().isBefore(enableTime)) {
				this.verifyResult = false;
				this.verifyMessage = "访问失败，未到该链接的启用时间。";
			}
		}
		return this;
	}


	/**
	 * 3、验证短链接映射过期时间
	 *
	 * @return 当前验证器
	 */
	public LinkMappingValidator verifyDisableTime() {
		if (this.verifyResult) {
			LocalDateTime disableTime = mapping.getDisableTime();
			if (Objects.nonNull(disableTime) && LocalDateTime.now().isAfter(disableTime)) {
				this.verifyResult = false;
				this.verifyMessage = "访问失败，该短链接已过期。";
			}
		}
		return this;
	}


	/**
	 * 4、验证短链接映射访问次数限制
	 *
	 * @param accessService 短链接访问Service
	 * @return 当前验证器
	 */
	public LinkMappingValidator verifyAllowTotal(SlLinkAccessService accessService) {
		if (this.verifyResult) {
			Long allowTotal = mapping.getAllowTotal();
			if (Objects.nonNull(allowTotal)) {
				// 已访问的次数
				long accessCount = accessService.count(
					Wrappers.lambdaQuery(SlLinkAccess.class)
						.eq(SlLinkAccess::getMappingKey, mapping.getMappingKey())
						.eq(SlLinkAccess::getResult, 1)
				);
				if (accessCount >= allowTotal) {
					this.verifyResult = false;
					this.verifyMessage = "访问失败，该链接已到达最大访问次数。";
				}
			}
		}
		return this;
	}


	/**
	 * 验证短链接映射访问密码
	 *
	 * @param accessPassword 访问密码
	 * @return 当前验证器
	 */
	public LinkMappingValidator verifyAccessPassword(String accessPassword) {
		if (this.verifyResult) {
			String password = mapping.getAccessPassword();
			if (Objects.nonNull(password) && !password.equals(accessPassword)) {
				this.verifyResult = false;
				this.verifyMessage = "访问失败，短链接访问密码错误。";
			}
		}
		return this;
	}

}
